/*
 * ArrayList.h
 *
 *  Created on: 25.09.2012
 *      Author: Lapchinskiy
 */
#include "Global_types.h"
#include "BuildConfig.h"
#include "Logging.h"
#include <string.h>
#ifndef ARRAYLIST_H_
#define ARRAYLIST_H_
const unsigned char listGrowStep = 2;
//enum ArrayListExeptionType {
//	INDEX_OUT_OF_RANGE, NO_ELEMENT_ON_REQUESTED_INDEX
//};

//class ArrayListExeption {
//public:
//	ArrayListExeptionType nameId;
//	ArrayListExeption(ArrayListExeptionType name_id) {
//		this->nameId = name_id;
//		this->nameId = name_id;
//	}
//};

template<class T>
class ArrayList {
public:
	ArrayList();
	ArrayList(uint16_t size);
	~ArrayList();
	ErrorCode add(T* newItem);
	ErrorCode add(T* newItem, uint16_t index);
	ErrorCode remove(uint16_t index);
	ErrorCode remove();
	T* get(uint16_t index);
	uint16_t getSize() const;
	uint16_t getLength() const;
	void setSize(uint16_t size);
private:
	T** arraybuf;
	uint16_t size;
	uint16_t indexPointer;
	const static uint16_t defaultsize = 5;
};

template<class T>
ArrayList<T>::ArrayList() {
	indexPointer = 0;
	size = defaultsize;
	arraybuf = new T*[size];
	indexPointer = 0;
}

template<class T>
ArrayList<T>::ArrayList(uint16_t size) {
	this->size = size;
	arraybuf = new T*[size];
	indexPointer = 0;

}

template<class T>
ArrayList<T>::~ArrayList() {
	delete[] arraybuf;
}

template<class T>
ErrorCode ArrayList<T>::add(T* newItem) {
	if (indexPointer >= size) {
		T** arraybufTemp = new T*[size];
		memcpy((void*) arraybufTemp, (void*) arraybuf, sizeof(T*) * size);
		delete[] arraybuf;
		arraybuf = new T*[(size += listGrowStep)];
		memcpy((void*) arraybuf, (void*) arraybufTemp,
				sizeof(T*) * (size - listGrowStep));
		delete[] arraybufTemp;
	}
	arraybuf[indexPointer++] =newItem;//new T(*newItem);
	return NO_ERR;
}
template<class T>
ErrorCode ArrayList<T>::add(T* newItem, uint16_t index) {
	if (index >= size) {
		T** arraybufTemp = new T*[size];
		memcpy((void*) arraybufTemp, (void*) arraybuf, sizeof(T*) * size);
		delete[] arraybuf;
		arraybuf = new T*[(size += listGrowStep)];
		memcpy((void*) arraybuf, (void*) arraybufTemp,
				sizeof(T*) * (size - listGrowStep));
		delete[] arraybufTemp;
	}
	if (index < size) {
		arraybuf[index] = newItem;
		return NO_ERR;
	} else {
		//throw ArrayListExeption(INDEX_OUT_OF_RANGE);
	}
	return FAIL;

}

template<class T>
ErrorCode ArrayList<T>::remove(uint16_t index) {
	if (index > indexPointer - 1) {
		//throw ArrayListExeption(INDEX_OUT_OF_RANGE);
	}

	return FAIL;
}

template<class T>
ErrorCode ArrayList<T>::remove() {

	return FAIL;
}

template<class T>
T* ArrayList<T>::get(uint16_t index) {
	if (index < indexPointer) {
		return arraybuf[index];
	} else {
		size = 0;
		index = 0;
		//throw ArrayListExeption(INDEX_OUT_OF_RANGE);
	}
	return 0;
}

template<class T>
uint16_t ArrayList<T>::getSize() const {
	return this->size;
}

template<class T>
uint16_t ArrayList<T>::getLength() const {
	return this->indexPointer;
}

template<class T>
inline void ArrayList<T>::setSize(uint16_t size) {
}

#endif /* ARRAYLIST_H_ */

